/**
 * 关系图工具方法
 */

/**
 * 创建圆形头像符号
 * @param {string} avatarUrl 头像URL
 * @param {number} nodeSize 节点大小
 * @returns {string} 圆形头像的base64数据URL
 */
export function createCircleAvatarSymbol(avatarUrl, nodeSize) {
  return new Promise((resolve, reject) => {
    // #ifdef H5
    const img = new Image();
    img.crossOrigin = 'anonymous';
    
    img.onload = function() {
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      
      const size = nodeSize || 40;
      canvas.width = size;
      canvas.height = size;
      
      // 创建圆形裁剪路径
      ctx.beginPath();
      ctx.arc(size / 2, size / 2, size / 2, 0, 2 * Math.PI);
      ctx.clip();
      
      // 绘制头像
      ctx.drawImage(img, 0, 0, size, size);
      
      const dataUrl = canvas.toDataURL();
      resolve(`image://${dataUrl}`);
    };
    
    img.onerror = function() {
      console.warn('头像加载失败:', avatarUrl);
      resolve('circle');
    };
    
    img.src = avatarUrl;
    // #endif
    
    // #ifndef H5
    // 小程序环境下，直接使用普通符号
    resolve('circle');
    // #endif
  });
}

/**
 * 获取节点符号
 * @param {Object} node 节点数据
 * @returns {string} 节点符号
 */
export function getNodeSymbol(node) {
  return 'circle';
}

/**
 * 处理节点头像符号
 * @param {Array} nodes 节点数组
 * @param {Function} callback 处理完成的回调
 */
export function processNodeAvatars(nodes, callback) {
  const promises = nodes.map(node => {
    if (node._needAvatarSymbol && node._avatarUrl) {
      return createCircleAvatarSymbol(node._avatarUrl, node._nodeSize)
        .then(symbol => {
          node.symbol = symbol;
          return node;
        })
        .catch(() => {
          node.symbol = 'circle';
          return node;
        });
    }
    return Promise.resolve(node);
  });
  
  Promise.all(promises).then(processedNodes => {
    callback(processedNodes);
  });
}

/**
 * 数据过滤工具
 * @param {Array} nodes 节点数组
 * @param {Array} edges 边数组
 * @param {Array} selectedTypes 选中的关系类型
 * @param {Object} filterValues 过滤条件
 * @returns {Object} 过滤后的数据
 */
export function filterGraphData(nodes, edges, selectedTypes, filterValues = {}) {
  const nodeIds = new Set(nodes.map(n => String(n.id)));
  
  // 过滤边
  const filteredEdges = edges.filter(edge => {
    const typeMatched = selectedTypes.includes(edge.type);
    const sourceExists = nodeIds.has(String(edge.source));
    const targetExists = nodeIds.has(String(edge.target));
    return typeMatched && sourceExists && targetExists;
  });

  // 收集有连线的节点ID
  const connectedNodeIds = new Set();
  filteredEdges.forEach(edge => {
    connectedNodeIds.add(String(edge.source));
    connectedNodeIds.add(String(edge.target));
  });

  // 过滤节点
  const filteredNodes = nodes.filter(node =>
    connectedNodeIds.has(String(node.id))
  );

  return {
    nodes: filteredNodes,
    edges: filteredEdges
  };
}

/**
 * 生成图表配置选项
 * @param {Object} params 配置参数
 * @returns {Object} ECharts配置选项
 */
export function generateChartOption(params) {
  const {
    nodes,
    edges,
    layoutMode,
    setting,
    nodeConfig,
    graphStyle
  } = params;

  const finalNodes = nodes.map(node => {
    const nodeSize = setting?.nodeSize || nodeConfig.size || (node.type === 'company' ? 50 : 40);
    
    const nodeConfig = {
      ...node,
      id: String(node.id),
      draggable: true,
      symbolSize: nodeSize,
      cursor: 'pointer',
      category: node.type === 'company' ? 0 : 1,
      symbol: getNodeSymbol(node),
      itemStyle: {
        color: setting?.nodeColor || nodeConfig.color || (node.type === 'company' ? '#10B981' : '#8B5CF6'),
        borderWidth: 0,
        shadowBlur: 6,
        shadowColor: 'rgba(0, 0, 0, 0.15)'
      }
    };

    // 设置标签
    const hasAvatar = node.avatarUrl && node.avatarUrl.trim() !== '';
    const nodeName = node.name || node.text;
    
    if (hasAvatar) {
      nodeConfig._needAvatarSymbol = true;
      nodeConfig._avatarUrl = node.avatarUrl;
      nodeConfig._nodeSize = nodeSize;
      
      nodeConfig.label = {
        show: nodeName ? true : false,
        position: 'bottom',
        formatter: nodeName || '',
        fontSize: Math.max(10, Math.min(13, nodeSize / 4)),
        color: '#fff',
        fontWeight: 'bold',
        distance: 5,
        backgroundColor: '#4285f4',
        padding: [3, 8],
        borderRadius: 12,
        shadowBlur: 4,
        shadowColor: 'rgba(66, 133, 244, 0.3)'
      };
    } else {
      nodeConfig.label = {
        show: nodeName ? true : false,
        position: 'inside',
        formatter: nodeName || '',
        fontSize: Math.max(10, Math.min(14, nodeSize / 3)),
        color: '#fff',
        fontWeight: 'bold'
      };
    }

    // 处理坐标
    if (layoutMode === 'none') {
      nodeConfig.x = typeof node.x === 'number' ? node.x : 0;
      nodeConfig.y = typeof node.y === 'number' ? node.y : 0;
      nodeConfig.fixed = true;
    }

    return nodeConfig;
  });

  return {
    backgroundColor: setting?.backgroundColor || graphStyle.backgroundColor || 'transparent',
    tooltip: { 
      show: false
    },
    animationDurationUpdate: layoutMode === 'none' ? 0 : 1500,
    animationEasingUpdate: 'quinticInOut',
    series: [{
      type: 'graph',
      layout: layoutMode,
      draggable: true,
      symbolSize: setting?.nodeSize || nodeConfig.size || 40,
      roam: true,
      force: {
        repulsion: 800,
        edgeLength: 120,
        gravity: 0.3,
        friction: 0.4,
        layoutAnimation: true
      },
      edgeSymbol: ['none', 'arrow'],
      edgeSymbolSize: [0, 10],
      edgeLabel: {
        fontSize: 12,
        color: '#666'
      },
      data: finalNodes,
      links: edges.map(edge => ({
        ...edge,
        source: String(edge.source),
        target: String(edge.target)
      })),
      itemStyle: {
        borderWidth: 0,
        shadowBlur: 6,
        shadowColor: 'rgba(0, 0, 0, 0.15)'
      },
      lineStyle: {
        color: '#999',
        width: setting?.edgeWidth || 2,
        opacity: 0.8,
        curveness: 0.2
      },
      emphasis: {
        focus: 'adjacency',
        label: {
          position: 'right',
          show: true
        }
      },
      categories: [
        { name: 'company', symbol: 'rect' },
        { name: 'person', symbol: 'circle' }
      ]
    }]
  };
}

/**
 * 保存图片到相册
 * @param {Object} chartInstance 图表实例
 */
export function saveChartAsImage(chartInstance) {
  return new Promise((resolve, reject) => {
    if (!chartInstance) {
      reject(new Error('图表实例不存在'));
      return;
    }

    try {
      // #ifdef H5
      // H5端保存图片
      const dataURL = chartInstance.getDataURL({
        pixelRatio: 2,
        backgroundColor: '#fff'
      });
      
      const link = document.createElement('a');
      link.download = `关系图_${new Date().getTime()}.png`;
      link.href = dataURL;
      link.click();
      resolve();
      // #endif
      
      // #ifndef H5
      // 小程序和APP端保存图片
      const canvasId = 'relationGraphCanvas';
      chartInstance.renderToCanvas({
        canvasId: canvasId,
        success: (canvas) => {
          uni.canvasToTempFilePath({
            canvasId: canvasId,
            success: (res) => {
              uni.saveImageToPhotosAlbum({
                filePath: res.tempFilePath,
                success: () => {
                  resolve();
                },
                fail: (err) => {
                  reject(err);
                }
              });
            },
            fail: (err) => {
              reject(err);
            }
          });
        },
        fail: (err) => {
          reject(err);
        }
      });
      // #endif
    } catch (error) {
      reject(error);
    }
  });
}

/**
 * 图表缩放工具
 * @param {Object} chartInstance 图表实例
 * @param {number} scale 缩放比例
 */
export function zoomChart(chartInstance, scale) {
  if (!chartInstance) return;
  
  try {
    chartInstance.dispatchAction({
      type: 'graphRoam',
      zoom: scale
    });
  } catch (error) {
    console.warn('图表缩放失败:', error);
  }
}

/**
 * 重置图表视图
 * @param {Object} chartInstance 图表实例
 */
export function resetChartView(chartInstance) {
  if (!chartInstance) return;
  
  try {
    chartInstance.dispatchAction({
      type: 'restore'
    });
  } catch (error) {
    console.warn('重置图表视图失败:', error);
  }
} 